Dockerのscratchイメージを探検する
はじめに
Amazon EC2 Container Service (ECS): ECSエージェントの動作を確認するを書いている中で、scratchイメージの存在を知りました。
This image is most useful in the context of building base images or super minimal images
とのことで、超最小化されたベースイメージのようです。超最小というだけあってshさえ入っておらず、コンテナの中にシェルログインしようとしても入れません。
$ sudo docker run -it scratch /bin/sh exec: "/bin/sh": stat /bin/sh: no such file or directoryFATA[0000] Error response from daemon: Cannot start container f7eb41a5e71f6c9357267ae572f3e990698c2ee54854dd362fefec88a29f2108: exec: "/bin/sh": stat /bin/sh: no such file or directory
ということで、このscrachイメージの中にログインできるようにして、中身を確認してみました。
やってみた
実行した環境はAmazon Linuxです。
要は、scrachイメージにshコマンドを追加したイメージを作って、コンテナ起動すれば良い訳です。ただ単純shコマンドをコピーしても、依存している共有ライブラリが無いと動きません。なので/bin/shが依存している共有ライブラリをlddコマンドで確認します。
$ ldd /bin/sh linux-vdso.so.1 => (0x00007fff3bffe000) libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f934d17f000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f934cf7a000) libc.so.6 => /lib64/libc.so.6 (0x00007f934cbd5000) /lib64/ld-linux-x86-64.so.2 (0x00007f934d3a9000)
作業用ディレクトリを作り、shコマンドとその依存している共有ライブラリをコピーします。
$ mkdir work;cd work $ cp /bin/sh ./ $ cp /lib64/libtinfo.so.5 ./ $ cp /lib64/libdl.so.2 ./ $ cp /lib64/libc.so.6 ./ $ cp /lib64/ld-linux-x86-64.so.2 ./ $ ls ld-linux-x86-64.so.2 libc.so.6 libdl.so.2 libtinfo.so.5 sh
scratchイメージにshコマンドを追加するためのDockerfileを作成します。
$ vi Dockerfile FROM scratch COPY ./sh /bin/sh COPY ./libtinfo.so.5 /lib64/libtinfo.so.5 COPY ./libdl.so.2 /lib64/libdl.so.2 COPY ./libc.so.6 /lib64/libc.so.6 COPY ./ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 CMD ["/bin/sh"]
docker buildします。
$ sudo docker build -t local/sh . Sending build context to Docker daemon 3.212 MB Sending build context to Docker daemon Step 0 : FROM scratch ---> 511136ea3c5a Step 1 : COPY ./sh /bin/sh ---> Using cache ---> d888ba3ab54c Step 2 : COPY ./libtinfo.so.5 /lib64/libtinfo.so.5 ---> Using cache ---> 391272660fd9 Step 3 : COPY ./libdl.so.2 /lib64/libdl.so.2 ---> Using cache ---> e612a1cd98af Step 4 : COPY ./libc.so.6 /lib64/libc.so.6 ---> Using cache ---> 1197f1569133 Step 5 : COPY ./ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 ---> Using cache ---> b8b023b3f1dd Step 6 : CMD /bin/sh ---> Using cache ---> d64311c33f95 Successfully built d64311c33f95
これでshコマンドを含めたscratchイメージが出来ました。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE local/sh latest d64311c33f95 33 seconds ago 3.206 MB
ではコンテナ起動します!
$ sudo docker run -it local/sh /bin/sh sh-4.1#
はい、ログイン出来ましたね!
しかしlsコマンドもありません...
sh-4.1# ls sh: ls: command not found
仕方がないのでechoで代用します。
sh-4.1# echo * bin dev etc lib64 proc sys sh-4.1# cd /sys sh-4.1# echo * block bus class dev devices firmware fs hypervisor kernel module power sh-4.1# cd /etc sh-4.1# echo * hostname hosts mtab resolv.conf
本当に最小限のものしか入っていないようですね。そんなわけで、scratchイメージの内容が見えるようになりました!
さいごに
Docker関連はやってもやっても新しい発見ばかりです。本当はもっとECSに特化して勉強するつもりだったのですが、すっかり横道に逸れました。でも楽しいです!